#include "PlanWidget.h"
#include "TaskEditDialog.h"
#include "TaskCompleteDialog.h"
#include "PlanService.h"
#include "SoundService.h"
#include "TimerService.h"
#include "StyleLoader.h"
#include "log.h"
#include <QHBoxLayout>
#include <QMessageBox>
#include <QButtonGroup>
#include <QIcon>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QFrame>
#include <QFileDialog>
#include <QPalette>
#include <QColor>
#include <QEvent>
#include <QUuid>
#include <algorithm>  // std::sort

PlanWidget::PlanWidget(QWidget *parent)
    : FramelessWindow(parent)
    , m_viewMode(DayView)
    , m_currentDate(QDate::currentDate())
    , m_dateEdit(new QDateEdit(this))
    , m_todayBtn(new QPushButton("今天", this))
    , m_quickAddEdit(new QLineEdit(this))
    , m_addTaskBtn(new QPushButton("详细", this))
    , m_refreshBtn(new QPushButton(this))
    , m_dayViewBtn(new QPushButton("日", this))
    , m_weekViewBtn(new QPushButton("周", this))
    , m_viewButtonGroup(new QButtonGroup(this))
    , m_dateRangeLabel(new QLabel(this))
    , m_taskCountLabel(new QLabel("任务: 0", this))
    , m_scrollArea(new QScrollArea(this))
    , m_taskContainer(new QWidget())
    , m_taskLayout(new QVBoxLayout(m_taskContainer))
    , m_emptyLabel(new QLabel("暂无任务\n点击「+ 新建任务」开始", this))
{
    configureWindowFrame();
    setupUi();
    applyDefaultStyle();
    updateFrameAppearance();
    updateMaximizeButtonIcon();
    setupConnections();
    refreshTasks();

    // 启动提醒检查
    PlanService::instance().startReminderCheck();
    logInfo("PlanWidget 初始化完成");
}

PlanWidget::~PlanWidget()
{
    PlanService::instance().stopReminderCheck();
    logInfo("PlanWidget 已销毁");
}

// [FDD-2025-03-015][AC-001] 紧凑模式实现
void PlanWidget::setCompactMode(bool compact)
{
    if (m_compactMode == compact) {
        return;
    }

    m_compactMode = compact;
    if (compact) {
        const bool wasVisible = isVisible();
        if (m_exportBtn) m_exportBtn->setVisible(false);
        if (m_importBtn) m_importBtn->setVisible(false);
        if (m_refreshBtn) m_refreshBtn->setVisible(false);
        if (m_todayBtn) m_todayBtn->setVisible(false);
        if (m_dayViewBtn) m_dayViewBtn->setVisible(false);
        if (m_weekViewBtn) m_weekViewBtn->setVisible(false);
        if (m_filterCombo) m_filterCombo->setVisible(false);
        if (m_searchEdit) m_searchEdit->setVisible(false);
        if (m_dateEdit) m_dateEdit->setVisible(false);
        if (m_dateRangeLabel) m_dateRangeLabel->setVisible(false);
        if (m_taskCountLabel) m_taskCountLabel->setVisible(false);
        if (m_titleWidget) m_titleWidget->setVisible(false);
        if (m_addTaskBtn) m_addTaskBtn->setVisible(false);

        // [FDD-2025-03-015][UX] 紧凑模式下优化快速添加栏
        if (m_quickAddEdit) {
            m_quickAddEdit->setPlaceholderText(tr("快速添加任务..."));
            m_quickAddEdit->setMinimumHeight(28);
            m_quickAddEdit->setMaximumHeight(28);
        }

        if (m_contentLayout) {
            m_contentLayout->setContentsMargins(6, 4, 6, 4);  // 更紧凑的边距
            m_contentLayout->setSpacing(4);  // 减小间距
        }

        setStyleSheet(
            "QWidget { "
            "  background-color: #2b2b2b; "
            "  color: #e0e0e0; "
            "}"
            "QPushButton { "
            "  background-color: #3c3c3c; "
            "  border: 1px solid #555; "
            "  border-radius: 4px; "
            "  padding: 4px 8px; "
            "  color: #e0e0e0; "
            "}"
            "QPushButton:hover { "
            "  background-color: #4a4a4a; "
            "}"
            "QLineEdit { "
            "  background-color: #3c3c3c; "
            "  border: 1px solid #555; "
            "  border-radius: 4px; "
            "  padding: 6px; "
            "  color: #e0e0e0; "
            "}"
            "QScrollArea { "
            "  background-color: #2b2b2b; "
            "  border: none; "
            "}"
            );

        if (m_frameWidget) {
            m_frameWidget->setStyleSheet("QWidget#planFrameWidget { background-color: #2b2b2b; border-radius: 6px; }");
        }

        setResizeable(false);
        setOnlyMoveByTitlebar(false);

        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::Window;
        flags &= ~Qt::FramelessWindowHint;
        flags &= ~Qt::WindowStaysOnTopHint;
        setWindowFlags(flags | Qt::Widget);
        setAttribute(Qt::WA_TranslucentBackground, false);
        setAttribute(Qt::WA_NoSystemBackground, false);
        setAttribute(Qt::WA_StyledBackground, true);
        setAutoFillBackground(true);

        QPalette pal = palette();
        pal.setColor(QPalette::Window, QColor("#2b2b2b"));
        setPalette(pal);

        if (wasVisible) {
            show();
        }

        updateGeometry();
        update();
        logDebug("[PlanWidget] Compact mode enabled - most controls hidden");
    } else {
        if (m_exportBtn) m_exportBtn->setVisible(true);
        if (m_importBtn) m_importBtn->setVisible(true);
        if (m_refreshBtn) m_refreshBtn->setVisible(true);
        if (m_todayBtn) m_todayBtn->setVisible(true);
        if (m_dayViewBtn) m_dayViewBtn->setVisible(true);
        if (m_weekViewBtn) m_weekViewBtn->setVisible(true);
        if (m_filterCombo) m_filterCombo->setVisible(true);
        if (m_searchEdit) m_searchEdit->setVisible(true);
        if (m_dateEdit) m_dateEdit->setVisible(true);
        if (m_addTaskBtn) m_addTaskBtn->setVisible(true);
        if (m_dateRangeLabel) m_dateRangeLabel->setVisible(true);
        if (m_taskCountLabel) m_taskCountLabel->setVisible(true);
        if (m_titleWidget) m_titleWidget->setVisible(true);
        if (m_quickAddEdit) {
            m_quickAddEdit->setPlaceholderText(tr("输入任务标题后可按回车..."));
            m_quickAddEdit->setMinimumHeight(40);
        }

        if (m_contentLayout) {
            m_contentLayout->setContentsMargins(20, 20, 20, 20);
            m_contentLayout->setSpacing(12);
        }

        setAttribute(Qt::WA_StyledBackground, false);
        if (!parentWidget()) {
            setAttribute(Qt::WA_TranslucentBackground, true);
            setAutoFillBackground(false);
        }

        setResizeable(true);
        setOnlyMoveByTitlebar(true);

        if (!m_defaultStyleSheet.isEmpty()) {
            setStyleSheet(m_defaultStyleSheet);
        } else {
            applyDefaultStyle();
        }

        if (!parentWidget()) {
            Qt::WindowFlags restoreFlags = Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint;
            setWindowFlags(restoreFlags);
            show();
        }
        updateFrameAppearance();
        logDebug("[PlanWidget] Compact mode disabled");
    }
}

void PlanWidget::configureWindowFrame()
{
    setWindowTitle(tr("任务计划"));
    setWindowIcon(QIcon(":/resource/ico/DesktopTimer.ico"));
    setMinimumSize(800, 520);
    setResizeable(true);
    setOnlyMoveByTitlebar(true);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setAttribute(Qt::WA_NoSystemBackground, false);
}

void PlanWidget::setupTitleBar(QVBoxLayout *frameLayout)
{
    if (!frameLayout) {
        return;
    }
    m_titleWidget = new QWidget(this);
    m_titleWidget->setObjectName("planTitleBar");
    m_titleWidget->setFixedHeight(TITLE_BAR_HEIGHT);
    m_titleWidget->setStyleSheet(
        "QWidget#planTitleBar { "
        "  background-color: #3C3C3E; "
        "  border-top-left-radius: 8px; "
        "  border-top-right-radius: 8px; "
        "  border-bottom: 1px solid #444444; "
        "}"
        );

    auto* titleLayout = new QHBoxLayout(m_titleWidget);
    titleLayout->setContentsMargins(12, 0, 12, 0);
    titleLayout->setSpacing(6);
    frameLayout->addWidget(m_titleWidget);
    m_titleIcon = new QLabel(m_titleWidget);
    m_titleIcon->setFixedSize(20, 20);
    m_titleIcon->setStyleSheet("background-image:url(:/resource/svg/time.svg);border:none;");
    titleLayout->addWidget(m_titleIcon);

    m_titleLabel = new QLabel(tr("任务计划"), m_titleWidget);
    m_titleLabel->setStyleSheet("color:#E0E0E0;font-weight:bold;font-size:15px;border:none;");
    titleLayout->addWidget(m_titleLabel);
    titleLayout->addStretch();
    auto createButton = [](const QString &iconPath, const QString &hover) {
        QPushButton *btn = new QPushButton();
        btn->setCursor(Qt::PointingHandCursor);
        btn->setFixedSize(36, 32);
        btn->setStyleSheet(
            QStringLiteral(
                "QPushButton { "
                "  background-image: url(%1); "
                "  border: none; "
                "  background-repeat: no-repeat; "
                "  background-position: center; "
                "  border-radius: 4px; "
                "}"
                "QPushButton:hover { "
                "  background-color: %2; "
                "}"
                ).arg(iconPath, hover)
            );

        return btn;
    };

    m_minButton = createButton(":/resource/svg/minimize_20.svg", "#565656");
    titleLayout->addWidget(m_minButton);
    m_maxButton = createButton(":/resource/svg/maximize_20_normal.svg", "#565656");
    titleLayout->addWidget(m_maxButton);
    m_closeButton = createButton(":/resource/svg/close_20.svg", "#DE061A");
    titleLayout->addWidget(m_closeButton);

    setTitlebarWidgets({m_titleWidget, m_titleLabel});
    connect(m_minButton, &QPushButton::clicked, this, [this]() {
        setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
    });

    connect(m_maxButton, &QPushButton::clicked, this, &PlanWidget::toggleMaximizeState);
    connect(m_closeButton, &QPushButton::clicked, this, &PlanWidget::close);
}

void PlanWidget::applyDefaultStyle()
{
    QString theme = StyleLoader::loadDarkTheme();

    if (theme.isEmpty()) {
        theme = QStringLiteral(
            "QWidget { color:#E0E0E0; background-color:#2C2C2E; }"
            "QLineEdit, QComboBox { background-color:#3C3C3E; border:1px solid #555; border-radius:4px; padding:6px; }"
            );
    }

    const QString frameStyle = QStringLiteral(
        "QWidget#planFrameWidget { background-color: #2C2C2E; border-radius: 8px; }"
        "QWidget#planContentWidget { background-color: #2C2C2E; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; }"
        "QWidget#planTitleBar { background-color: #3C3C3E; border-top-left-radius: 8px; border-top-right-radius: 8px; }"
        );

    m_defaultStyleSheet = theme + frameStyle;

    setStyleSheet(m_defaultStyleSheet);

    updateFrameAppearance();
}

void PlanWidget::updateFrameAppearance()
{
    if (!m_frameWidget || !m_mainWidget) {
        return;
    }
    m_frameWidget->setContentsMargins(0, 0, 0, 0);
    m_mainWidget->setContentsMargins(0, 0, 0, 0);
}

void PlanWidget::toggleMaximizeState()
{
    if (windowState().testFlag(Qt::WindowMaximized)) {
        setWindowState(Qt::WindowNoState);
    } else {
        setWindowState(Qt::WindowMaximized);
    }
    updateMaximizeButtonIcon();
}

void PlanWidget::updateMaximizeButtonIcon()
{
    if (!m_maxButton) {
        return;
    }

    const bool maximized = windowState().testFlag(Qt::WindowMaximized);
    const QString iconPath = maximized ? ":/resource/svg/maximize_20_max.svg"
                                       : ":/resource/svg/maximize_20_normal.svg";
    m_maxButton->setStyleSheet(
        QStringLiteral(
            "QPushButton { "
            "  background-image: url(%1); "
            "  border: none; "
            "  background-repeat: no-repeat; "
            "  background-position: center; "
            ).arg(iconPath)
        );
}

void PlanWidget::changeEvent(QEvent *event)
{
    FramelessWindow::changeEvent(event);
    if (event->type() == QEvent::WindowStateChange) {
        updateMaximizeButtonIcon();
    }
}

void PlanWidget::setupUi()
{
    QVBoxLayout *outerLayout = new QVBoxLayout(this);
    outerLayout->setSpacing(0);
    outerLayout->setContentsMargins(0, 0, 0, 0);

    m_frameWidget = new QWidget(this);
    m_frameWidget->setObjectName("planFrameWidget");
    outerLayout->addWidget(m_frameWidget);

    QVBoxLayout *frameLayout = new QVBoxLayout(m_frameWidget);
    frameLayout->setSpacing(0);
    frameLayout->setContentsMargins(0, 0, 0, 0);

    setupTitleBar(frameLayout);
    m_mainWidget = new QWidget(m_frameWidget);
    m_mainWidget->setObjectName("planContentWidget");
    frameLayout->addWidget(m_mainWidget);

    m_contentLayout = new QVBoxLayout(m_mainWidget);
    m_contentLayout->setSpacing(12);
    m_contentLayout->setContentsMargins(20, 20, 20, 20);

    QHBoxLayout *toolbarLayout = new QHBoxLayout();
    toolbarLayout->setSpacing(10);

    m_dateEdit->setDate(m_currentDate);
    m_dateEdit->setCalendarPopup(true);
    m_dateEdit->setDisplayFormat("yyyy-MM-dd");
    m_todayBtn->setMaximumWidth(60);

    m_viewButtonGroup->addButton(m_dayViewBtn, DayView);
    m_viewButtonGroup->addButton(m_weekViewBtn, WeekView);
    m_dayViewBtn->setCheckable(true);
    m_weekViewBtn->setCheckable(true);
    m_dayViewBtn->setChecked(true);
    m_dayViewBtn->setMaximumWidth(50);
    m_weekViewBtn->setMaximumWidth(50);

    m_refreshBtn->setIcon(QIcon(":/resource/svg/refresh.svg"));
    m_refreshBtn->setIconSize(QSize(20, 20));
    m_refreshBtn->setText(QString());
    m_refreshBtn->setMaximumWidth(40);
    m_refreshBtn->setToolTip(tr("刷新任务列表"));

    m_exportBtn = new QPushButton(this);
    m_exportBtn->setIcon(QIcon(":/resource/svg/export.svg"));
    m_exportBtn->setIconSize(QSize(20, 20));
    m_exportBtn->setToolTip(tr("导出 CSV/JSON（包含当前视图）"));
    m_exportBtn->setMaximumWidth(40);

    m_importBtn = new QPushButton(this);
    m_importBtn->setIcon(QIcon(":/resource/svg/import.svg"));
    m_importBtn->setIconSize(QSize(20, 20));
    m_importBtn->setToolTip(tr("导入 CSV/JSON"));
    m_importBtn->setMaximumWidth(40);

    toolbarLayout->addWidget(m_dateEdit);
    toolbarLayout->addWidget(m_todayBtn);
    toolbarLayout->addWidget(m_dayViewBtn);
    toolbarLayout->addWidget(m_weekViewBtn);

    m_filterCombo = new QComboBox(this);
    m_filterCombo->addItem(tr("全部"));
    m_filterCombo->addItem(tr("待办"));
    m_filterCombo->addItem(tr("已完成"));

    m_filterCombo->setMaximumWidth(110);

    m_searchEdit = new QLineEdit(this);
    m_searchEdit->setPlaceholderText(tr("搜索标题或备注..."));
    m_searchEdit->setMaximumWidth(220);

    toolbarLayout->addStretch();
    toolbarLayout->addWidget(m_filterCombo);
    toolbarLayout->addWidget(m_searchEdit);
    toolbarLayout->addWidget(m_exportBtn);
    toolbarLayout->addWidget(m_importBtn);
    toolbarLayout->addWidget(m_refreshBtn);

    m_contentLayout->addLayout(toolbarLayout);

    QHBoxLayout *quickAddLayout = new QHBoxLayout();
    quickAddLayout->setSpacing(10);

    m_quickAddEdit->setPlaceholderText(tr("输入任务标题后按回车..."));
    m_quickAddEdit->setMinimumHeight(40);

    m_addTaskBtn->setMaximumWidth(90);
    m_addTaskBtn->setMinimumHeight(40);
    m_addTaskBtn->setToolTip(tr("打开详细编辑对话框"));
    m_addTaskBtn->setObjectName("primaryButton");

    quickAddLayout->addWidget(m_quickAddEdit);
    quickAddLayout->addWidget(m_addTaskBtn);
    m_contentLayout->addLayout(quickAddLayout);

    QHBoxLayout *infoLayout = new QHBoxLayout();
    m_dateRangeLabel->setVisible(false);

    infoLayout->addWidget(m_dateRangeLabel);
    infoLayout->addStretch();
    infoLayout->addWidget(m_taskCountLabel);
    m_contentLayout->addLayout(infoLayout);

    m_scrollArea->setParent(m_mainWidget);
    // [FDD-2025-03-015][UX] 滚动区域设置：
    // - setWidgetResizable(true)：让容器宽度自动匹配滚动区域，确保任务项能正确布局
    // - 垂直方向会根据内容高度自动扩展并显示滚动条
    m_scrollArea->setWidgetResizable(true);
    m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_scrollArea->setFrameShape(QFrame::NoFrame);

    m_taskLayout->setSpacing(0);  // 任务间距设为0，由TaskItemWidget的margin控制
    m_taskLayout->setContentsMargins(0, 0, 0, 0);
    // [FDD-2025-03-015][UX] 设置布局约束，确保容器根据内容自动调整高度
    m_taskLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
    // [FDD-2025-03-015][UX] 移除 stretch，避免滚动时底部任务被遮挡
    // m_taskLayout->addStretch();  // 不再需要 stretch

    m_taskContainer->setLayout(m_taskLayout);
    m_taskContainer->setAcceptDrops(true);
    m_taskContainer->installEventFilter(this);
    // [FDD-2025-03-015][UX] 容器尺寸策略：
    // - 水平方向 Expanding：填充 ScrollArea 宽度，确保任务项能正确布局
    // - 垂直方向 Minimum：根据任务数量自动扩展
    m_taskContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
    m_scrollArea->setWidget(m_taskContainer);

    m_contentLayout->addWidget(m_scrollArea);

    m_emptyLabel->setParent(m_mainWidget);
    m_emptyLabel->setAlignment(Qt::AlignCenter);
    m_emptyLabel->setVisible(false);
    m_contentLayout->addWidget(m_emptyLabel);
}

// 根据投递位置计算插入索引（日视图下）
int PlanWidget::indexForDropPosition(const QPoint &pos) const
{
    // 遍历现有任务组件，找到第一个其中心Y大于pos.y()的位置
    for (int i = 0; i < m_taskWidgets.size(); ++i) {
        TaskItemWidget *w = m_taskWidgets[i];
        if (!w) continue;

        QPoint rel = w->mapTo(m_taskContainer, QPoint(0, 0));
        int centerY = rel.y() + w->height() / 2;

        if (pos.y() < centerY) return i;
    }
    return m_taskWidgets.size();
}

void PlanWidget::updateDropIndicator(int index)
{
    if (m_viewMode != DayView) return;
    if (index < 0) index = 0;
    if (index > m_taskWidgets.size()) index = m_taskWidgets.size();

    if (!m_dropIndicator) {
        m_dropIndicator = new QWidget(m_taskContainer);
        m_dropIndicator->setFixedHeight(3);
        m_dropIndicator->setStyleSheet("background: #2196F3; border-radius: 2px;");
    }

    // 若位置未变化，则不操作
    if (m_dropIndicatorIndex == index && m_dropIndicator->isVisible()) return;

    // [FDD-2025-03-015][UX] 将指示器插入到布局中 index 位置
    // 先确保从布局中移除旧的
    int count = m_taskLayout->count();
    for (int i = 0; i < count; ++i) {
        QLayoutItem *it = m_taskLayout->itemAt(i);
        if (it && it->widget() == m_dropIndicator) {
            m_taskLayout->removeWidget(m_dropIndicator);
            break;
        }
    }

    // 计算插入位置（已移除 stretch，直接使用 count）
    int insertAt = qMin(index, m_taskLayout->count());
    if (insertAt < 0) insertAt = 0;

    m_taskLayout->insertWidget(insertAt, m_dropIndicator);
    m_dropIndicator->setVisible(true);
    m_dropIndicatorIndex = index;
}

void PlanWidget::hideDropIndicator()
{
    if (!m_dropIndicator) return;
    m_dropIndicator->setVisible(false);
    // 不必从布局移除，可复用；仅重置索引
    m_dropIndicatorIndex = -1;
}

bool PlanWidget::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == m_taskContainer) {
        // [FDD-2025-03-015] 紧凑模式禁用拖拽
        if (m_compactMode) {
            return false;
        }

        if (event->type() == QEvent::DragEnter) {
            QDragEnterEvent *e = static_cast<QDragEnterEvent*>(event);
            if (e->mimeData()->hasText() && m_viewMode == DayView) {
                e->acceptProposedAction();
                updateDropIndicator(indexForDropPosition(e->position().toPoint()));
                return true;
            }
        } else if (event->type() == QEvent::DragMove) {
            QDragMoveEvent *e = static_cast<QDragMoveEvent*>(event);
            if (e->mimeData()->hasText() && m_viewMode == DayView) {
                e->acceptProposedAction();
                updateDropIndicator(indexForDropPosition(e->position().toPoint()));
                return true;
            }
        } else if (event->type() == QEvent::DragLeave) {
            hideDropIndicator();
            return true;
        } else if (event->type() == QEvent::Drop) {
            QDropEvent *e = static_cast<QDropEvent*>(event);
            if (e->mimeData()->hasText() && m_viewMode == DayView) {
                QString draggedId = e->mimeData()->text();
                QPoint p = e->position().toPoint();
                int insertIndex = indexForDropPosition(p);

                // 生成新的顺序列表
                QStringList ids;
                for (TaskItemWidget* w : m_taskWidgets) {
                    if (w) ids << w->getTask().getId();
                }
                // 移除拖拽项
                ids.removeAll(draggedId);
                // 插入到新位置
                if (insertIndex < 0) insertIndex = 0;
                if (insertIndex > ids.size()) insertIndex = ids.size();
                ids.insert(insertIndex, draggedId);

                if (PlanService::instance().reorderTasks(m_currentDate, ids)) {
                    refreshTasks();
                }
                e->acceptProposedAction();
                hideDropIndicator();
                return true;
            }
        }
    }
    return FramelessWindow::eventFilter(watched, event);
}

bool PlanWidget::matchTask(const PlanTask &task) const
{
    if (m_filterMode == FilterMode::TodoOnly && task.getStatus() == TaskStatus::Completed) return false;

    if (m_filterMode == FilterMode::CompletedOnly && task.getStatus() != TaskStatus::Completed) return false;

    if (!m_searchKeyword.trimmed().isEmpty()) {
        const QString key = m_searchKeyword.trimmed();

        if (!task.getTitle().contains(key, Qt::CaseInsensitive) &&
            !task.getDescription().contains(key, Qt::CaseInsensitive)) {
            return false;
        }
    }

    return true;
}

void PlanWidget::onFilterChanged(int index)
{
    switch (index) {
    case 1: m_filterMode = FilterMode::TodoOnly; break;
    case 2: m_filterMode = FilterMode::CompletedOnly; break;
    default: m_filterMode = FilterMode::All; break;
    }
    refreshTasks();
}

void PlanWidget::onSearchChanged(const QString &text)
{
    m_searchKeyword = text;
    refreshTasks();
}

void PlanWidget::setupConnections()
{
    // UI事件
    connect(m_dateEdit, &QDateEdit::dateChanged, this, &PlanWidget::onDateChanged);
    connect(m_todayBtn, &QPushButton::clicked, this, &PlanWidget::onTodayClicked);
    connect(m_quickAddEdit, &QLineEdit::returnPressed, this, &PlanWidget::onQuickAddTask);
    connect(m_addTaskBtn, &QPushButton::clicked, this, &PlanWidget::onAddTaskClicked);
    connect(m_refreshBtn, &QPushButton::clicked, this, &PlanWidget::onRefreshClicked);
    connect(m_exportBtn, &QPushButton::clicked, this, &PlanWidget::onExportClicked);
    connect(m_importBtn, &QPushButton::clicked, this, &PlanWidget::onImportClicked);

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    connect(m_viewButtonGroup, &QButtonGroup::idClicked,
            this, &PlanWidget::onViewModeChanged);
#else
    connect(m_viewButtonGroup, QOverload<int>::of(&QButtonGroup::buttonClicked),
            this, &PlanWidget::onViewModeChanged);
#endif

    connect(m_filterCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlanWidget::onFilterChanged);
    connect(m_searchEdit, &QLineEdit::textChanged, this, &PlanWidget::onSearchChanged);

    // Service信号
    connect(&PlanService::instance(), &PlanService::tasksUpdated,
            this, &PlanWidget::onTasksUpdated);
    connect(&PlanService::instance(), &PlanService::taskReminderTriggered,
            this, &PlanWidget::onTaskReminderTriggered);
    connect(&PlanService::instance(), &PlanService::taskCompleted,
            this, &PlanWidget::onTaskCompleted);
}

void PlanWidget::refreshTasks()
{
    clearTaskList();

    if (m_viewMode == DayView) {
        m_currentDate = m_dateEdit->date();
        loadTasks(m_currentDate);
    } else {
        loadWeekTasks();
    }

    logDebug("用户刷新任务列表");
}

void PlanWidget::clearTaskList()
{
    // 清理现有任务小部件
    for (auto* widget : m_taskWidgets) {
        widget->deleteLater();
    }
    m_taskWidgets.clear();
}

void PlanWidget::loadTasks(const QDate& date)
{
    clearTaskList();

    QList<PlanTask> tasks = PlanService::instance().getTasks(date);

    // [FDD-2025-03-015][UX] 排序：未完成任务在前，已完成任务在后
    std::sort(tasks.begin(), tasks.end(), [](const PlanTask& a, const PlanTask& b) {
        // 第一优先级：按状态排序（未完成在前）
        bool aCompleted = (a.getStatus() == TaskStatus::Completed);
        bool bCompleted = (b.getStatus() == TaskStatus::Completed);

        if (aCompleted != bCompleted) {
            return !aCompleted;  // 未完成的在前
        }

        // 第二优先级：按排序顺序（sortOrder）
        if (a.getSortOrder() != b.getSortOrder()) {
            return a.getSortOrder() < b.getSortOrder();
        }

        // 第三优先级：按开始时间
        return a.getStartTime() < b.getStartTime();
    });

    // 应用过滤器和搜索
    int totalCount = 0;
    int displayCount = 0;

    for (const PlanTask& task : tasks) {
        totalCount++;
        bool matched = matchTask(task);
        if (matched) {
            addTaskWidget(task);
            displayCount++;
        }
    }

    // 更新任务计数标签
    if (m_taskCountLabel) {
        if (displayCount < totalCount) {
            m_taskCountLabel->setText(tr("任务: %1/%2").arg(displayCount).arg(totalCount));
        } else {
            m_taskCountLabel->setText(tr("任务: %1").arg(totalCount));
        }
    }

    // 显示或隐藏空状态标签
    if (m_emptyLabel) {
        m_emptyLabel->setVisible(m_taskWidgets.isEmpty());
    }

    // 隐藏周视图日期范围标签
    if (m_dateRangeLabel) {
        m_dateRangeLabel->setVisible(false);
    }

    // [FDD-2025-03-015][UX] 确保容器正确更新尺寸，支持滚动到所有任务
    m_taskContainer->updateGeometry();
    m_scrollArea->updateGeometry();
}

void PlanWidget::loadWeekTasks()
{
    clearTaskList();

    // 获取本周的日期范围（周一到周日）
    int dayOfWeek = QDate::currentDate().dayOfWeek();
    QDate startDate = QDate::currentDate().addDays(1 - dayOfWeek);
    QDate endDate = startDate.addDays(6);

    // 更新日期范围标签
    if (m_dateRangeLabel) {
        m_dateRangeLabel->setText(getWeekDateRange());
        m_dateRangeLabel->setVisible(true);
    }

    // 加载本周所有任务
    QList<PlanTask> allWeekTasks;
    QDate currentDate = startDate;
    while (currentDate <= endDate) {
        QList<PlanTask> dayTasks = PlanService::instance().getTasks(currentDate);
        allWeekTasks.append(dayTasks);
        currentDate = currentDate.addDays(1);
    }

    // [FDD-2025-03-015][UX] 排序：未完成任务在前，已完成任务在后
    std::sort(allWeekTasks.begin(), allWeekTasks.end(), [](const PlanTask& a, const PlanTask& b) {
        // 第一优先级：按状态排序（未完成在前）
        bool aCompleted = (a.getStatus() == TaskStatus::Completed);
        bool bCompleted = (b.getStatus() == TaskStatus::Completed);

        if (aCompleted != bCompleted) {
            return !aCompleted;  // 未完成的在前
        }

        // 第二优先级：按开始时间（日期+时间）
        if (a.getStartTime() != b.getStartTime()) {
            return a.getStartTime() < b.getStartTime();
        }

        // 第三优先级：按排序顺序
        return a.getSortOrder() < b.getSortOrder();
    });

    // 应用过滤器和搜索，添加任务小部件
    int totalCount = 0;
    int displayCount = 0;

    for (const PlanTask& task : allWeekTasks) {
        totalCount++;
        if (matchTask(task)) {
            addTaskWidget(task);
            displayCount++;
        }
    }

    // 更新任务计数标签
    if (m_taskCountLabel) {
        if (displayCount < totalCount) {
            m_taskCountLabel->setText(tr("任务: %1/%2").arg(displayCount).arg(totalCount));
        } else {
            m_taskCountLabel->setText(tr("任务: %1").arg(totalCount));
        }
    }

    // 显示或隐藏空状态标签
    if (m_emptyLabel) {
        m_emptyLabel->setVisible(m_taskWidgets.isEmpty());
    }

    // [FDD-2025-03-015][UX] 确保容器正确更新尺寸，支持滚动到所有任务
    m_taskContainer->updateGeometry();
    m_scrollArea->updateGeometry();
}

void PlanWidget::addTaskWidget(const PlanTask& task)
{
    TaskItemWidget* widget = new TaskItemWidget(task, m_taskContainer);

    // [FDD-2025-03-015] 如果是紧凑模式，设置 TaskItemWidget 为紧凑模式
    if (m_compactMode) {
        widget->setCompactMode(true);
    }

    // 连接任务小部件的信号
    connect(widget, &TaskItemWidget::statusToggled, this, &PlanWidget::onTaskStatusToggled);
    connect(widget, &TaskItemWidget::editRequested, this, &PlanWidget::onTaskEditRequested);
    connect(widget, &TaskItemWidget::deleteRequested, this, &PlanWidget::onTaskDeleteRequested);
    connect(widget, &TaskItemWidget::timerRequested, this, &PlanWidget::onTaskTimerRequested);

    // [FDD-2025-03-015][UX] 添加到布局末尾（已移除 stretch，直接添加即可）
    m_taskLayout->addWidget(widget);
    widget->show();  // 确保widget可见

    m_taskWidgets.append(widget);

    // [FDD-2025-03-015][UX] 确保容器和滚动区域正确更新尺寸
    m_taskContainer->updateGeometry();
    m_scrollArea->updateGeometry();
}

QString PlanWidget::getWeekDateRange() const
{
    int dayOfWeek = QDate::currentDate().dayOfWeek();
    QDate startDate = QDate::currentDate().addDays(1 - dayOfWeek);
    QDate endDate = startDate.addDays(6);

    return tr("%1 至 %2")
        .arg(startDate.toString("MM-dd"))
        .arg(endDate.toString("MM-dd"));
}

void PlanWidget::onExportClicked()
{
    QDate start = m_currentDate;
    QDate end = m_currentDate;

    if (m_viewMode == WeekView) {
        int dow = QDate::currentDate().dayOfWeek();
        QDate s = QDate::currentDate().addDays(1 - dow);
        start = s; 
        end = s.addDays(6);
    }

    QString filter = tr("JSON 文件 (*.json);;CSV 文件 (*.csv)");

    QString defName = (m_viewMode==DayView ? QString("plan-%1.json").arg(start.toString("yyyy-MM-dd"))
                                             : QString("plan-week-%1.json").arg(QDate::currentDate().toString("yyyy-ww")));

    QString file = QFileDialog::getSaveFileName(this, tr("导出任务"), defName, filter);

    if (file.isEmpty()) return;

    bool ok=false;

    if (file.endsWith(".json", Qt::CaseInsensitive)) ok = PlanService::instance().exportTasksToJson(start, end, file);
    else if (file.endsWith(".csv", Qt::CaseInsensitive)) ok = PlanService::instance().exportTasksToCsv(start, end, file);
    else { ok = PlanService::instance().exportTasksToJson(start, end, file + ".json"); }

    if (!ok) QMessageBox::warning(this, tr("导出失败"), tr("无法导出到指定文件"));
}

void PlanWidget::onImportClicked()
{
    QString filter = tr("JSON 文件 (*.json);;CSV 文件 (*.csv)");

    QString file = QFileDialog::getOpenFileName(this, tr("导入任务"), QString(), filter);

    if (file.isEmpty()) return;

    bool ok=false;

    if (file.endsWith(".json", Qt::CaseInsensitive)) ok = PlanService::instance().importTasksFromJson(file);
    else if (file.endsWith(".csv", Qt::CaseInsensitive)) ok = PlanService::instance().importTasksFromCsv(file);

    if (!ok) {
        QMessageBox::warning(this, tr("导入失败"), tr("请检查文件格式是否正确"));
    } else {
        refreshTasks();
    }
}

// ========== TaskItem信号槽 ==========

void PlanWidget::onTaskStatusToggled(const QString &taskId, bool completed)
{
    if (completed) {
        // 用户标记为完成，弹出对话框记录过程
        // 先获取任务对象
        QList<PlanTask> tasks = PlanService::instance().getTasks(m_currentDate);
        PlanTask targetTask;
        bool found = false;

        for (const PlanTask& task : tasks) {
            if (task.getId() == taskId) {
                targetTask = task;
                found = true;
                break;
            }
        }

        if (!found) {
            logWarning("未找到任务: " << taskId);
            return;
        }

        // 弹出完成对话框
        TaskCompleteDialog dialog(targetTask, this);
        if (dialog.exec() == QDialog::Accepted) {
            // [FDD-2025-11] 获取更新后的任务对象（包含所有新字段）
            targetTask = dialog.getUpdatedTask();

            // 将结束时间设置为当前时间（实际完成时间）
            targetTask.setEndTime(QDateTime::currentDateTime());

            PlanService::instance().updateTask(targetTask);
        } else {
            // 用户取消，不标记完成（恢复复选框状态）
            refreshTasks();
        }
    } else {
        // 取消完成状态
        PlanService::instance().toggleTaskStatus(taskId, m_currentDate);
    }
}

void PlanWidget::onTaskEditRequested(const PlanTask &task)
{
    TaskEditDialog dialog(task, this);
    if (dialog.exec() == QDialog::Accepted) {
        PlanTask updatedTask = dialog.getTask();
        PlanService::instance().updateTask(updatedTask);
        refreshTasks();
    }
}

void PlanWidget::onTaskDeleteRequested(const QString &taskId)
{
    // 获取任务所属日期
    QDate taskDate = m_currentDate;

    // 如果是周视图，需要找到任务的实际日期
    if (m_viewMode == WeekView) {
        // 遍历任务小部件找到对应的任务
        for (TaskItemWidget* widget : m_taskWidgets) {
            if (widget && widget->getTask().getId() == taskId) {
                taskDate = widget->getTask().getStartTime().date();
                break;
            }
        }
    }

    auto reply = QMessageBox::question(this, tr("确认删除"),
                                       tr("确定要删除这个任务吗？"),
                                       QMessageBox::Yes | QMessageBox::No);
    if (reply == QMessageBox::Yes) {
        PlanService::instance().deleteTask(taskId, taskDate);
        refreshTasks();
        logInfo("用户删除任务: " << taskId << " 日期: " << taskDate.toString("yyyy-MM-dd"));
    }
}

void PlanWidget::onTaskTimerRequested(const PlanTask &task)
{
    // 触发计时请求信号，启动计时器
    logInfo("用户请求为任务计时: " << task.getTitle());

    // 计算任务的预期时长（如果设置了结束时间）
    int durationMinutes = 25; // 默认番茄钟时长（25分钟）

    if (task.getEndTime().isValid() && task.getStartTime().isValid()) {
        qint64 seconds = task.getStartTime().secsTo(task.getEndTime());
        durationMinutes = static_cast<int>(seconds / 60);

        // 限制时长范围（1分钟到480分钟/8小时）
        durationMinutes = qBound(1, durationMinutes, 480);
    }

    // 启动计时器（转换为毫秒）
    int durationMs = durationMinutes * 60 * 1000;
    TimerService::instance().startTimer(durationMs, TimerMode::Countdown);

    logInfo("已启动计时器: " << task.getTitle()
            << " 时长: " << durationMinutes << " 分钟");

    // 显示通知或反馈
    if (QWidget* mainWindow = window()) {
        logDebug("计时器已启动，主窗口应显示计时器界面");
    }
}

void PlanWidget::onDateChanged(const QDate &date)
{
    m_currentDate = date;
    if (m_viewMode == DayView) {
        loadTasks(date);
    }
}

void PlanWidget::onViewModeChanged(int id)
{
    m_viewMode = static_cast<ViewMode>(id);
    if (m_viewMode == DayView) {
        m_dateEdit->setEnabled(true);
        loadTasks(m_currentDate);
    } else {
        m_dateEdit->setEnabled(false);
        loadWeekTasks();
    }
    updateFrameAppearance();
}

void PlanWidget::onTodayClicked()
{
    m_currentDate = QDate::currentDate();
    m_dateEdit->setDate(m_currentDate);
    if (m_viewMode == DayView) {
        loadTasks(m_currentDate);
    }
}

void PlanWidget::onQuickAddTask()
{
    QString title = m_quickAddEdit->text().trimmed();
    if (title.isEmpty()) return;

    // 使用 PlanService::createTask 创建任务
    QDateTime startTime = QDateTime::currentDateTime();
    QDateTime endTime = startTime.addSecs(3600); // 默认1小时

    PlanTask task = PlanService::instance().createTask(title, startTime, endTime);

    // 任务默认状态为 Todo（在 createTask 中已设置）

    m_quickAddEdit->clear();
    refreshTasks();
    logInfo("快速添加任务: " << title);
}

void PlanWidget::onAddTaskClicked()
{
    TaskEditDialog dialog(this);
    if (dialog.exec() == QDialog::Accepted) {
        PlanTask newTask = dialog.getTask();
        // 使用 updateTask 保存任务（TaskEditDialog 已创建任务对象）
        PlanService::instance().updateTask(newTask);
        refreshTasks();
        logInfo("用户添加任务: " << newTask.getTitle());
    }
}

void PlanWidget::onRefreshClicked()
{
    refreshTasks();
}

void PlanWidget::onTasksUpdated(const QDate &date)
{
    // PlanService通知任务更新时刷新列表
    if (m_viewMode == DayView && date == m_currentDate) {
        refreshTasks();
    } else if (m_viewMode == WeekView) {
        refreshTasks();
    }
}

void PlanWidget::onTaskReminderTriggered(const PlanTask &task)
{
    // 任务提醒触发时的处理
    logInfo("任务提醒触发: " << task.getTitle());

    // 1. 播放提醒声音（使用系统默认提示音）
    SoundService::instance().playSound(":/resource/sound/reminder.wav", 80);

    // 2. 在任务列表中高亮显示该任务
    for (TaskItemWidget* widget : m_taskWidgets) {
        if (widget && widget->getTask().getId() == task.getId()) {
            // 高亮显示任务（通过改变背景色）
            widget->setStyleSheet(
                "TaskItemWidget { "
                "  background-color: #3C5A99; "  // 蓝色高亮
                "  border: 2px solid #5B9BD5; "
                "  border-radius: 6px; "
                "}"
            );

            // 滚动到该任务位置
            if (m_scrollArea) {
                m_scrollArea->ensureWidgetVisible(widget);
            }

            // 3秒后恢复正常样式
            QTimer::singleShot(3000, widget, [widget]() {
                widget->setStyleSheet(""); // 恢复默认样式
            });

            logDebug("已高亮显示任务: " << task.getTitle());
            break;
        }
    }

    // 3. 显示系统通知（如果支持）
    // 在主窗口中可以使用 QSystemTrayIcon::showMessage
    logInfo("任务提醒已触发，播放声音并高亮显示任务");
}

void PlanWidget::onTaskCompleted(const PlanTask &task)
{
    // 任务完成时的处理
    logInfo("任务已完成: " << task.getTitle());
    refreshTasks();
}

